package database

import (
	"fmt"
	"github.com/bmatsuo/lmdb-go/lmdb"
)

// LMDb客户端结构体  只创建一个LMDb环境，一个DB库
type LMDbClient struct {
	Env *lmdb.Env
	DBI lmdb.DBI
}

func NewClient(size int64, path, name string) (*LMDbClient, error) {
	// 获取LMDb环境
	env, err := lmdb.NewEnv()
	if err != nil {
		return nil, err
	}

	// 设置最大存储
	err = env.SetMapSize(size)

	// 设置最大库数量
	if err = env.SetMaxDBs(1); err != nil {
		return nil, err
	}

	// 环境打开,Open an environment handle
	// mode:UNIX权限，用于设置创建的文件和信号量。
	if err = env.Open(path, 0, 0644); err != nil {
		return nil, err
	}

	var dbi lmdb.DBI
	err = env.View(func(txn *lmdb.Txn) (err error) {
		dbi, err = txn.OpenDBI(name, 0)
		return
	})

	if err != nil {
		err = env.Update(func(txn *lmdb.Txn) (err error) {
			dbi, err = txn.CreateDBI(name)
			return
		})

		if err != nil {
			return nil, err
		} else {
			fmt.Println("------------------- Create New DB ----------------")
		}
	}

	return &LMDbClient{env, dbi}, nil
}

// 插入
func (c *LMDbClient) Set(key, val []byte) error {
	return c.Env.Update(func(txn *lmdb.Txn) error { return txn.Put(c.DBI, key, val, 0) })
}

// 查询
func (c *LMDbClient) Get(key []byte) (data []byte, err error) {

	a, _ := c.Env.Info()
	fmt.Println(a)

	err = c.Env.View(func(txn *lmdb.Txn) (err error) {
		data, err = txn.Get(c.DBI, key)
		return err
	})
	return data, err
}

// 遍历
func (c *LMDbClient) Cursor() error {
	err := c.Env.View(func(txn *lmdb.Txn) (err error) {
		cur, err := txn.OpenCursor(c.DBI)
		if err != nil {
			return err
		}
		defer cur.Close()

		for {
			k, v, err := cur.Get(nil, nil, lmdb.Prev)
			if lmdb.IsNotFound(err) {
				return nil
			}
			if err != nil {
				return err
			}

			fmt.Printf("%s %s\n", k, v)
			return nil
		}
	})
	return err
}
